import time
import network
import ntptime
from machine import RTC, Pin
import usocket as socket
import os
from config_manager import get_wifi_config, load_config, set_wifi_config

def wifi_connect(ssid=None, password=None, timeout=10):
    # If no credentials provided, load from config
    if ssid is None or password is None:
        wifi_config = get_wifi_config()
        ssid = wifi_config.get('ssid', '')
        password = wifi_config.get('password', '')
    
    if not ssid:
        print("No SSID provided and none found in config")
        return False
        
    # Initialize WLAN interface
    wlan = network.WLAN(network.STA_IF)
    
    # Ensure WiFi interface is active
    if not wlan.active():
        print('Activating WiFi interface...')
        wlan.active(True)
    
    # Check if already connected
    if wlan.isconnected():
        current_ssid = wlan.config('essid')
        if current_ssid == ssid:
            print('Already connected to ' + ssid)
            config = wlan.ifconfig()
            print('IP:', config[0])
            print('Mask:', config[1])
            print('Gateway:', config[2])
            return True
        else:
            print('Connected to different WiFi: ' + current_ssid)
            print('Disconnecting...')
            wlan.disconnect()
            time.sleep(1)
    else:
        print('Not connected to WiFi')
    
    # Connect to WiFi
    print('Connecting to WiFi: ' + ssid)
    wlan.connect(ssid, password)
    
    # Wait for connection to complete, max 15 seconds
    max_wait = 15
    while max_wait > 0:
        if wlan.isconnected():
            break
        max_wait -= 1
        print('Waiting... ' + str(max_wait))
        time.sleep(1)
    
    # Check connection status
    if wlan.isconnected():
        config = wlan.ifconfig()
        print('WiFi connected!')
        print('IP:', config[0])
        print('Mask:', config[1])
        print('Gateway:', config[2])
        return True
    else:
        print('WiFi connect failed!')
        print('Status:', wlan.status())
        return False

def start_ap_mode(ssid='bcg_c3', password=''):
    """
    Start WiFi in Access Point mode with the specified SSID and password.
    If password is empty, it will be an open network.
    """
    # Deactivate station mode if active
    wlan_sta = network.WLAN(network.STA_IF)
    if wlan_sta.active():
        wlan_sta.active(False)
        time.sleep(1)
    
    # Configure AP mode
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    
    # Configure AP settings
    if password:
        # With password (WPA2)
        ap.config(essid=ssid, password=password)
    else:
        # Open network
        ap.config(essid=ssid, security=0)
    
    # Set static IP for AP
    ap.ifconfig(('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8'))
    
    # Wait for AP to be ready
    while ap.status() != network.STAT_GOT_IP:
        time.sleep(0.5)
    
    print('Access Point started!')
    print('SSID:', ssid)
    print('Password:', 'None' if not password else '*' * len(password))
    print('AP IP:', ap.ifconfig()[0])
    return ap

def handle_http_request(request):
    """
    Handle HTTP requests for the configuration portal.
    """
    # Parse request
    if request.startswith('POST'):
        # Extract POST data
        post_start = request.find('\r\n\r\n') + 4
        post_data = request[post_start:]
        
        # Parse form data
        params = {}
        for param in post_data.split('&'):
            if '=' in param:
                key, value = param.split('=')
                # Simple URL decode
                key = key.replace('+', ' ')
                value = value.replace('+', ' ')
                params[key] = value
        
        # Check if it's a WiFi config request
        if 'ssid' in params and 'password' in params:
            ssid = params['ssid']
            password = params['password']
            
            # Save WiFi configuration
            if set_wifi_config(ssid, password):
                response = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n'
                response += '<!DOCTYPE html><html><head><title>Configuration Successful</title></head>'
                response += '<body><h1>Configuration Saved!</h1>'
                response += '<p>WiFi SSID: ' + ssid + '</p>'
                response += '<p>Device will now restart to apply changes.</p>'
                response += '</body></html>'
                return response, True  # Return True to indicate restart needed
    
    # Default response: WiFi configuration form
    response = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n'
    response += '<!DOCTYPE html><html><head><title>ESP32C3 WiFi Config</title></head>'
    response += '<body><h1>Configure WiFi</h1>'
    response += '<form method="post">'
    response += '<div>SSID: <input type="text" name="ssid" required></div><br>'
    response += '<div>Password: <input type="password" name="password"></div><br>'
    response += '<input type="submit" value="Save">'
    response += '</form></body></html>'
    return response, False

def run_config_server():
    """
    Run HTTP server for WiFi configuration portal.
    """
    # Create socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
    # Bind to all interfaces on port 80
    s.bind(('0.0.0.0', 80))
    s.listen(5)
    
    print('Configuration server started on http://192.168.4.1')
    print('Connect to WiFi network "bcg_c3" and open the URL in a browser')
    
    restart_needed = False
    
    try:
        while not restart_needed:
            # Accept connection
            conn, addr = s.accept()
            print('Client connected from:', addr)
            
            # Receive request
            request = conn.recv(1024).decode('utf-8')
            print('Received request:', request[:100] + '...' if len(request) > 100 else request)
            
            # Handle request
            response, restart_needed = handle_http_request(request)
            
            # Send response
            conn.send(response.encode('utf-8'))
            conn.close()
            
            # Small delay to ensure client receives response before restart
            if restart_needed:
                time.sleep(2)
    
    except Exception as e:
        print('Server error:', e)
    finally:
        s.close()
        
    # If restart is needed, reset the device
    if restart_needed:
        print('Restarting device to apply new configuration...')
        time.sleep(1)
        import machine
        machine.reset()

def sync_time_from_ntp():
    # Try multiple NTP servers to improve success rate
    # Load configuration
    config = load_config()
    ntp_config = config.get('ntp', {})
    ntp_servers = ntp_config.get('servers', ['pool.ntp.org', 'ntp.aliyun.com', 'time.apple.com'])
    max_retries = ntp_config.get('max_retries', 2)
    retry_interval = ntp_config.get('retry_interval', 2)
    settings = config.get('settings', {})
    timezone_offset = settings.get('timezone_offset', 8)
    
    for server in ntp_servers:
        for attempt in range(max_retries):
            try:
                print('Sync time from ' + server + ' (attempt ' + str(attempt + 1) + '/' + str(max_retries) + ')...')
                # Set current NTP server
                ntptime.host = server
                
                # Sync time
                ntptime.settime()
                
                # Adjust to configured timezone
                import utime
                tm = ntptime.time() + timezone_offset * 3600
                local_time = utime.localtime(tm)
                
                # Print network time
                year, month, day, hour, minute, second, weekday, yearday = local_time
                print('NTP sync success with ' + server + '!')
                print('Time:', str(year) + '-' + str(month) + '-' + str(day), 
                      str(hour) + ':' + str(minute) + ':' + str(second))
                
                # Sync to RTC
                rtc = RTC()
                rtc.datetime((year, month, day, weekday, hour, minute, second, 0))
                
                return True
            except Exception as e:
                print('NTP error with ' + server + ': ' + str(e))
                if attempt < max_retries - 1:
                    print('Retrying in ' + str(retry_interval) + ' seconds...')
                    time.sleep(retry_interval)
    
    print('All NTP servers failed after retries')
    return False

def get_current_time():
    try:
        rtc = RTC()
        year, month, day, weekday, hour, minute, second, _ = rtc.datetime()
        
        # 格式化时间
        time_str = str(year) + '-' + str(month) + '-' + str(day) + ' '
        time_str += str(hour) + ':' + str(minute) + ':' + str(second)
        print('Current time:', time_str)
        
        return time_str
    except Exception as e:
        print('Get time error: ' + str(e))
        return None

if __name__ == '__main__':
    # Main program
    print('ESP32C3 WiFi Manager')
    
    # Load configuration
    config = load_config()
    wifi_config = config.get('wifi', {})
    
    # Get WiFi credentials from config
    ssid = wifi_config.get('ssid', '')
    password = wifi_config.get('password', '')
    
    # Check if WiFi credentials are configured
    if ssid:
        print(f'Found WiFi configuration: {ssid}')
        print('Trying to connect...')
        
        # Try to connect with saved credentials
        if wifi_connect(ssid, password):
            # Connection successful, continue with normal operation
            # 同步NTP时间
            if sync_time_from_ntp():
                # 打印几次时间
                for i in range(3):
                    get_current_time()
                    time.sleep(2)
                print('Test completed')
            else:
                print('Time sync failed')
        else:
            print('WiFi connection failed, starting configuration portal...')
            # Start AP mode and config server
            start_ap_mode(ssid='bcg_c3')
            run_config_server()
    else:
        print('No WiFi configuration found, starting configuration portal...')
        # No WiFi config, start AP mode and config server
        start_ap_mode(ssid='bcg_c3')
        run_config_server()